package com.example.utils;

import com.example.pojo.sandbox.ExecuteMessage;
import lombok.SneakyThrows;
import org.apache.tomcat.util.buf.StringUtils;
import org.springframework.stereotype.Component;
import org.springframework.util.StopWatch;


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;

/**
 * 进程工具类
 */
@Component
public class ProcessUtils {

    // 执行进程并获取信息
    @SneakyThrows
    public ExecuteMessage runProcessAndGetMessage(Process process) {
        // 创建信息类用来封装要返回的信息
        ExecuteMessage message = new ExecuteMessage();
        // 使用StopWatch工具来监控进程的执行时间
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        // 等待程序执行获取退出码,封装到返回信息中
        int exitValue = process.waitFor();
        message.setExitValue(exitValue);
        // 获取进程的正常输出封装到返回信息中（无论是正常退出或异常退出都需要读取进程的正常输出信息）
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
        message.setMessage(getOutputList(bufferedReader));
        // 异常退出
        if (exitValue != 0) {
            // 获取进程的异常输出并封装到返回信息中
            BufferedReader errorBufferedReader = new BufferedReader(new InputStreamReader(process.getErrorStream()));
            message.setErrorMessage(getOutputList(errorBufferedReader));
        }
        // 计时结束封装返回信息
        stopWatch.stop();
        message.setTime(stopWatch.getLastTaskTimeMillis());
        return message;
    }

    // 获取输出流输出信息
    private String getOutputList(BufferedReader bufferedReader) throws IOException {
        // 记录输出的信息
        ArrayList<String> outputList = new ArrayList<>();
        // 分批获取输出
        String outputLine;
        while ((outputLine = bufferedReader.readLine()) != null) {
            outputList.add(outputLine);
        }
        // 将输出转为字符串返回
        return StringUtils.join(outputList, '\n');
    }

}
